package org.point.common.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/**
 * dom4j解析XML工具类
 *
 */
public class Dom4jHelper {

	/**
	 * 创建文档实例
	 * 
	 * @return Document
	 */
	public static Document createDocument() {
		return DocumentHelper.createDocument();
	}

	/**
	 * 解析文件，获得根元素
	 * 
	 * @param xmlPath
	 * @param encoding
	 * @return
	 * @throws Exception
	 */
	public static Element parse(String xmlPath, String encoding)
			throws Exception {
		// 文件是否存在
		File file = new File(xmlPath);
		if (!file.exists()) {
			throw new Exception("找不到xml文件：" + xmlPath);
		}

		// 解析
		SAXReader reader = new SAXReader(false);
		Document doc = reader.read(new FileInputStream(file), encoding);
		Element root = doc.getRootElement();
		return root;
	}

	/**
	 * 保存文档
	 * 
	 * @param doc
	 * @param xmlPath
	 * @param encoding
	 * @throws Exception
	 */
	public static void save(Document doc, String xmlPath, String encoding)
			throws Exception {
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding(encoding);
		XMLWriter writer = new XMLWriter(new OutputStreamWriter(
				new FileOutputStream(xmlPath), encoding), format);
		writer.write(doc);
		writer.flush();
		writer.close();
	}

	/**
	 * 修改xml某节点的属性值
	 * 
	 * @param inputXml
	 *            原xml文件
	 * @param nodes
	 *            要修改的节点(格式//元素/@属性)
	 * @param oldValue
	 *            原属性值
	 * @param newValue
	 *            新值
	 * @param outXml
	 *            输出文件路径及文件名 如果输出文件为null，则默认为原xml文件
	 */
	public static void modifyAttrValue(File inputXml, String nodes,
			String oldValue, String newValue, String outXml) throws Exception {
		SAXReader saxReader = new SAXReader();
		Document document = saxReader.read(inputXml);
		List list = document.selectNodes(nodes);
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			Attribute attribute = (Attribute) iter.next();
			if (attribute.getValue().equals(oldValue)) {
				attribute.setValue(newValue);
			}
		}
		XMLWriter output;
		if (outXml != null) { // 指定输出文件
			output = new XMLWriter(new FileWriter(new File(outXml)));
		} else { // 输出文件为原文件
			output = new XMLWriter(new FileWriter(inputXml));
		}
		output.write(document);
		output.close();

	}

	/**
	 * 修改xml某元素的文本
	 * 
	 * @param inputXml
	 *            原xml文件
	 * @param nodes
	 *            要修改的节点(格式//元素)
	 * @param oldValue
	 *            原值
	 * @param newValue
	 *            新值
	 * @param outXml
	 *            输出文件路径及文件名 如果输出文件为null，则默认为原xml文件
	 */
	public static void modifyElementValue(File inputXml, String nodes,
			String oldValue, String newValue, String outXml)
			throws DocumentException, IOException {
		SAXReader saxReader = new SAXReader();
		Document document = saxReader.read(inputXml);
		List list = document.selectNodes(nodes);
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			Element element = (Element) iter.next();
			if (element.getText().equals(oldValue))
				element.setText(newValue);
		}
		XMLWriter output;
		if (outXml != null) { // 指定输出文件
			output = new XMLWriter(new FileWriter(new File(outXml)));
		} else { // 输出文件为原文件
			output = new XMLWriter(new FileWriter(inputXml));
		}
		output.write(document);
		output.close();
	}

	/**
	 * Document转换为字符串
	 * 
	 * @param doc
	 * @param encoding
	 * @return
	 * @throws Exception
	 */
	public static String toString(Document doc, String encoding)
			throws Exception {
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding(encoding);
		ByteArrayOutputStream byteOS = new ByteArrayOutputStream();
		XMLWriter writer = new XMLWriter(new OutputStreamWriter(byteOS,
				encoding), format);
		writer.write(doc);
		writer.flush();
		writer.close();
		writer = null;

		return byteOS.toString(encoding);
	}

	/**
	 * 字符串转换为Document
	 * 
	 * @param text
	 * @return
	 * @throws DocumentException
	 */
	public static Document str2Document(String text) throws DocumentException {
		Document document = DocumentHelper.parseText(text);
		return document;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		File f = new File("E:\\mybatis-generator-cfg.xml");
		try {
			Dom4jHelper.modifyElementValue(f, "//property", "aaa", "bbb",
					null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
